﻿using System;
using System.Windows;
using System.Windows.Controls;
using Dsl.Ped.Framework.Helpers;
using Dsl.Ped.Framework.Common;

namespace Dsl.Ped.Framework.Projections
{
    public class ProjectionFactoryBase
    {
        /// <summary>
        /// Initialize the projection of a specific <see cref="FrameworkElement"/> view
        /// and configure it properly via default and custom configurations
        /// </summary>
        /// <typeparam name="T">Type of projection view</typeparam>
        /// <param name="projectionHint">Projection hint that contains default and custom configurations</param>
        /// <param name="type">Type of the property which the projection is bound to</param>
        /// <returns><see cref="FrameworkElement"/> that represents a view of the projection</returns>
        public static T InitializeProjection<T>(
            IProjectionHint<T> projectionHint, Type type) where T : FrameworkElement, new()
        {
            var projection = Activator.CreateInstance(typeof(T)) as T;

            if (projection == null)
            {
                throw new ArgumentException("Projection must inherit the FrameworkElement");
            }

            // Execute default configuration specific to the element type
            if (projectionHint.DefaultConfiguration != null)
            {
                projectionHint.DefaultConfiguration(projection, type);
            }

            // Execute custom action to configure the projection
            if (projectionHint.CustomConfiguration != null)
            {
                projectionHint.CustomConfiguration(projection);
            }
            

            return projection;
        }

        /// <summary>
        /// Get Default configuration <see cref="Action"/> which is executed before
        /// any custom <see cref="Action"/> for the <see cref="FrameworkElement"/>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        protected static Action<T> GetDefaultFrameworkElementConfiguration<T>() where T : FrameworkElement
        {
            return frameworkElement => frameworkElement.SetValue(Validation.ErrorTemplateProperty,
                                                                 TemplateHelper.GetValidationErrorTemplate());
        }
    }
}
